BrightonSchoolSIM

Author

Adam Dennett

Spatial Interaction Demand Model for Brighton Schools

Origins - Brighton LSOAs and Pupils in 2024

Reading layer `BrightonLSOA_Clean' from data source 
  `E:\BH_Schools_2\data\BrightonLSOA_Clean.geojson' using driver `GeoJSON'
Simple feature collection with 165 features and 27 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -0.2450499 ymin: 50.79908 xmax: -0.0160027 ymax: 50.89237
Geodetic CRS:  WGS 84
Reading layer `lsoa_btn_pw_cent' from data source 
  `E:\BH_Schools_2\data\lsoa_btn_pw_cent.geojson' using driver `GeoJSON'
Simple feature collection with 165 features and 1 field
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 524624.9 ymin: 102198.2 xmax: 538674.1 ymax: 109563.7
Projected CRS: OSGB36 / British National Grid
Reading layer `LSOA_NOMIS_plus_projections' from data source 
  `E:\BH_Schools_2\data\LSOA_NOMIS_plus_projections.geojson' 
  using driver `GeoJSON'
replacing null geometries with empty geometries
Simple feature collection with 3465 features and 5 fields (with 3465 geometries empty)
Geometry type: GEOMETRYCOLLECTION
Dimension:     XY
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Geodetic CRS:  WGS 84
Reading layer `BrightonSecondaryCatchments' from data source 
  `E:\BH_Schools_2\data\BrightonSecondaryCatchments.geojson' 
  using driver `GeoJSON'
Simple feature collection with 6 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 523887.8 ymin: 100896.4 xmax: 539613.4 ymax: 110190.1
Projected CRS: OSGB36 / British National Grid
Reading layer `optionA' from data source `E:\BH_Schools_2\data\optionA.geojson' using driver `GeoJSON'
Simple feature collection with 6 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 523889.3 ymin: 100892.8 xmax: 540295.5 ymax: 110191.6
Projected CRS: OSGB36 / British National Grid
Reading layer `optionB' from data source `E:\BH_Schools_2\data\optionB.geojson' using driver `GeoJSON'
Simple feature collection with 4 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 523890.5 ymin: 100894.1 xmax: 539613.1 ymax: 110186.1
Projected CRS: OSGB36 / British National Grid

Destinations - Brighton Secondary Schools

Interactions

[1] "21"
Reading layer `oa_brighton' from data source 
  `E:\BH_Schools_2\data\oa_brighton.geojson' using driver `GeoJSON'
Simple feature collection with 936 features and 10 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 523598.1 ymin: 101780.1 xmax: 539862.4 ymax: 111919.1
Projected CRS: OSGB36 / British National Grid

Set up for the travel time matrix

[1] "lsoa21cd" "geometry" "2024"     "fid"      "lon"      "lat"     
[1] 1650
[1] "data.frame"

Cost - Travel Time Along the Road Network

Map the flows

Reading layer `catchement_01' from data source 
  `E:\BH_Schools_2\data\BTN_catchments\Catchment vectorised\catchment_01.geojson' 
  using driver `GeoJSON'
Simple feature collection with 6 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 524022.7 ymin: 101601.6 xmax: 539862.4 ymax: 110470.1
Projected CRS: OSGB36 / British National Grid
Reading layer `catchement_02' from data source 
  `E:\BH_Schools_2\data\BTN_catchments\Catchment vectorised\catchment_02.geojson' 
  using driver `GeoJSON'
Simple feature collection with 4 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -0.2391914 ymin: 50.79736 xmax: -0.0160027 ymax: 50.87872
Geodetic CRS:  WGS 84
Reading layer `catchment_03a' from data source 
  `E:\BH_Schools_2\data\BTN_catchments\Catchment vectorised\catchment_03a.geojson' 
  using driver `GeoJSON'
Simple feature collection with 8 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -0.2391914 ymin: 50.79736 xmax: -0.0160027 ymax: 50.87872
Geodetic CRS:  WGS 84
Error in wk_handle.wk_wkb(wkb, s2_geography_writer(oriented = oriented,  : 
  Loop 0 is not valid: Edge 45 crosses edge 47
Simple feature collection with 165 features and 19 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 524624.9 ymin: 102198.2 xmax: 538674.1 ymax: 109563.7
Projected CRS: OSGB36 / British National Grid
# A tibble: 165 × 20
   geography `2021` `2022` `2023` `2024` `2025` `2026` `2027` `2028` `2029`
 * <chr>      <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
 1 E01016958  14.3   13.5   13.4   14.4   13.5   13.9   13.8   13.2   12.6 
 2 E01016908  26.0   24.5   24.3   26.1   24.5   25.2   25.0   23.9   22.8 
 3 E01016983  21.4   20.2   20.0   21.5   20.2   20.8   20.6   19.7   18.8 
 4 E01016989  18.6   17.5   17.4   18.7   17.5   18.1   17.9   17.1   16.3 
 5 E01016919  13.7   12.9   12.8   13.7   12.9   13.2   13.1   12.6   12.0 
 6 E01016884  20.7   19.5   19.3   20.8   19.5   20.1   19.8   19.0   18.1 
 7 E01016941   4.99   4.70   4.66   5.01   4.70   4.84   4.79   4.60   4.38
 8 E01016899   8.96   8.44   8.37   9.00   8.44   8.69   8.60   8.25   7.86
 9 E01016998  23.3   21.9   21.8   23.4   22.0   22.6   22.4   21.5   20.4 
10 E01016925  16.3   15.3   15.2   16.4   15.3   15.8   15.6   15.0   14.3 
# ℹ 155 more rows
# ℹ 10 more variables: `2030` <dbl>, `2031` <dbl>, `2024_scaling_fact` <dbl>,
#   `2026_scaling_fact` <dbl>, `2030_scaling_fact` <dbl>,
#   `2024_scaled_BTN_places` <dbl>, `2026_scaled_BTN_places` <dbl>,
#   `2030_scaled_BTN_places` <dbl>, fid <int>, geometry <POINT [m]>
Error in wk_handle.wk_wkb(wkb, s2_geography_writer(oriented = oriented,  : 
  Loop 0 is not valid: Edge 45 crosses edge 47

Something here to look at PANs vs Places and FSM in 2024 for different catchment options

#first aggregate PAN, FSM etc to each of the different x, a, c, C catchment designs

optionX_stats <- brighton_sec_schools_sml %>%
  select(optionX, school_capacity, number_of_pupils, fsm, pan2024, pan2026, pan2030, contains('count')) %>%
  group_by(optionX) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE), .groups = 'drop') %>% 
  mutate(fsm_pct = round(fsm/number_of_pupils, 2)) %>% 
  relocate(fsm_pct, .after = fsm) %>% 
  st_drop_geometry()

optionA_stats <- brighton_sec_schools_sml %>%
  select(optionA, school_capacity, number_of_pupils, fsm, pan2024, pan2026, pan2030, contains('count')) %>%
  group_by(optionA) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE), .groups = 'drop') %>% 
  mutate(fsm_pct = round(fsm/number_of_pupils, 2)) %>% 
  relocate(fsm_pct, .after = fsm) %>% 
  st_drop_geometry()

optionB_stats <- brighton_sec_schools_sml %>%
  select(optionB, school_capacity, number_of_pupils, fsm, pan2024, pan2026, pan2030, contains('count')) %>%
  group_by(optionB) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE), .groups = 'drop') %>% 
  mutate(fsm_pct = round(fsm/number_of_pupils, 2)) %>% 
  relocate(fsm_pct, .after = fsm) %>% 
  st_drop_geometry()

optionC_stats <- brighton_sec_schools_sml %>%
  select(optionC, school_capacity, number_of_pupils, fsm, pan2024, pan2026, pan2030, contains('count')) %>%
  group_by(optionC) %>%
  summarise(across(where(is.numeric), sum, na.rm = TRUE), .groups = 'drop') %>% 
  mutate(fsm_pct = round(fsm/number_of_pupils, 2)) %>% 
  relocate(fsm_pct, .after = fsm) %>% 
  st_drop_geometry()


#now join the stats back to the catchment polygons

optionX_summarised <- optionX_summarised %>% 
  left_join(optionX_stats, by = c("catchment" = "optionX"))

optionA_summarised <- optionA_summarised %>%
  left_join(optionA_stats, by = c("catchment" = "optionA"))

optionB_summarised <- optionB_summarised %>%
  left_join(optionB_stats, by = c("catchment" = "optionB"))

optionC_summarised <- optionC_summarised %>%
  left_join(optionC_stats, by = c("catchment" = "optionC"))

# Display the results

# Create the map for optionC
tm_shape(optionA_summarised) +
  tm_polygons(
    col = "fsm_pct",
    popup.vars = c("Catchment" = "catchment", "FSM %" = "fsm_pct"),
    palette = "Purples",
    title = "FSM %"
  ) +
  tm_layout(
    legend.show = TRUE,
    title = "Option A"
  ) +
tm_shape(optionB_summarised) +
  tm_polygons(
    col = "fsm_pct",
    popup.vars = c("Catchment" = "catchment", "FSM %" = "fsm_pct"),
    palette = "Purples",
    title = "FSM %"
  ) +
  tm_layout(
    legend.show = TRUE,
    title = "Option B"
  ) +
tm_shape(optionC_summarised) +
  tm_polygons(
    col = "fsm_pct",
    popup.vars = c("Catchment" = "catchment", "FSM %" = "fsm_pct"),
    palette = "Purples",
    title = "FSM %"
  ) +
  tm_layout(
    legend.show = TRUE,
    title = "Option C"
  )

Work out total commuting time as minutes x pupils for each place in each catchment currently

Picking a distance-decay beta parameter

https://transportgeography.org/contents/methods/spatial-interactions-gravity-model/spatial-interactions-beta-alpha-lambda/

[1] 2560
[1] 2560
# A tibble: 10 × 2
   dest   prodSIM1
   <chr>     <dbl>
 1 114579     296.
 2 114580     281.
 3 114581     176.
 4 114606     273.
 5 114607     322.
 6 114608     234.
 7 114611     385.
 8 136164     173.
 9 137063     199.
10 139409     220.
     orig               dest                flow         
 Length:1650        Length:1650        Min.   : 0.03876  
 Class :character   Class :character   1st Qu.: 0.51329  
 Mode  :character   Mode  :character   Median : 0.95700  
                                       Mean   : 1.55151  
                                       3rd Qu.: 1.84295  
                                       Max.   :18.70974  
     orig               dest                flow       
 Length:1650        Length:1650        Min.   :  4.00  
 Class :character   Class :character   1st Qu.: 56.00  
 Mode  :character   Mode  :character   Median : 85.00  
                                       Mean   : 92.34  
                                       3rd Qu.:121.00  
                                       Max.   :281.00  
[1] 1650
[1] 1650

Gravity Model Longhill

Gravity Model BACA